package com.geekhalo.lego.plugin.resultconverter;

import com.geekhalo.lego.plugin.creator.JavaFileCreator;
import com.geekhalo.lego.plugin.support.util.Utils;
import com.intellij.ide.util.ClassFilter;
import com.intellij.ide.util.TreeClassChooser;
import com.intellij.ide.util.TreeClassChooserFactory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.GlobalSearchScope;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;

public class CreateResultConverterDialog extends DialogWrapper {
    private JPanel contentPane;
    private JTextField cxtClassName;
    private JButton selectCxtTypeBtn;
    private JTextField aggClassName;
    private JButton selectAggTypeBtn;
    private JTextField converterTypeName;
    private JTextField resultClassName;
    private JButton selectResultTypeBtn;

    private final Project project;
    private final Module module;
    private final String pkg;
    private String cxtTypeFull;
    private String aggTypeFull;

    public CreateResultConverterDialog(Project project, Module module, String pkg,
                                       String cxtTypeFull,
                                       String aggTypeFull) {
        super(project);
        this.project = project;
        this.module = module;
        this.pkg = pkg;
        this.cxtTypeFull = cxtTypeFull;
        this.aggTypeFull = aggTypeFull;

        setModal(true);

        initComponent();
        super.init();
    }

    private void initComponent() {
        if (StringUtils.isNotEmpty(this.cxtTypeFull)) {
            this.cxtClassName.setText(this.cxtTypeFull);
        }
        if (StringUtils.isNotEmpty(this.aggTypeFull)) {
            this.aggClassName.setText(this.aggTypeFull);
        }

        // 选择Context类
        this.selectCxtTypeBtn.addActionListener(e->{
            TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(project);
            // 设置过滤条件，只选择 public 类型的类
            ClassFilter classFilter = psiClass -> psiClass.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC);
            // 弹出选择类的窗口
            TreeClassChooser chooser = factory.createWithInnerClassesScopeChooser(
                    "选择Context类",
                    GlobalSearchScope.allScope(project),
                    classFilter,
                    null);
            chooser.showDialog();
            // 获取用户选择的类
            PsiClass selectedClass = chooser.getSelected();
            // 如果用户选择了类，则在控制台输出类名
            if (selectedClass != null) {
                this.cxtClassName.setText(selectedClass.getQualifiedName());
            }
        });

        // 选择 Agg 类
        this.selectAggTypeBtn.addActionListener(e->{
            TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(project);
            // 设置过滤条件，只选择 public 类型的类
            ClassFilter classFilter = psiClass -> psiClass.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC);
            // 弹出选择类的窗口
            TreeClassChooser chooser = factory.createWithInnerClassesScopeChooser(
                    "选择Agg类",
                    GlobalSearchScope.allScope(project),
                    classFilter,
                    null);
            chooser.showDialog();
            // 获取用户选择的类
            PsiClass selectedClass = chooser.getSelected();
            // 如果用户选择了类，则在控制台输出类名
            if (selectedClass != null) {
                this.aggClassName.setText(selectedClass.getQualifiedName());
            }
        });

        // 选择 Result 类
        this.selectResultTypeBtn.addActionListener(e->{
            TreeClassChooserFactory factory = TreeClassChooserFactory.getInstance(project);
            // 设置过滤条件，只选择 public 类型的类
            ClassFilter classFilter = psiClass -> psiClass.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC);
            // 弹出选择类的窗口
            TreeClassChooser chooser = factory.createWithInnerClassesScopeChooser(
                    "选择Result类",
                    GlobalSearchScope.allScope(project),
                    classFilter,
                    null);
            chooser.showDialog();
            // 获取用户选择的类
            PsiClass selectedClass = chooser.getSelected();
            // 如果用户选择了类，则在控制台输出类名
            if (selectedClass != null) {
                this.resultClassName.setText(selectedClass.getQualifiedName());
                updateConverterClass(selectedClass.getName());
            }
        });

    }

    private void updateConverterClass(String name) {
        String converterName = Utils.createConverterName(name);
        this.converterTypeName.setText(converterName);
    }

    @Override
    protected @Nullable JComponent createCenterPanel() {
        return contentPane;
    }
    @Override
    protected void doOKAction(){
        createFiles();
        super.doOKAction();
    }

    @Override
    public void doCancelAction(){
        super.doCancelAction();
    }

    private void createFiles() {
        if (StringUtils.isEmpty(this.converterTypeName.getText())){
            Messages.showMessageDialog("类名不能为null", "ERROR", null);
            return;
        }
        if (StringUtils.isEmpty(this.cxtClassName.getText())){
            Messages.showMessageDialog("Context不能为null", "ERROR", null);
            return;
        }
        if (StringUtils.isEmpty(this.aggClassName.getText())){
            Messages.showMessageDialog("聚合不能为null", "ERROR", null);
            return;
        }

        if (StringUtils.isEmpty(this.resultClassName.getText())){
            Messages.showMessageDialog("返回结果不能为null", "ERROR", null);
            return;
        }

        ResultConverterTemplate.CreateResultConverterContext context =
                new ResultConverterTemplate.CreateResultConverterContext(this.pkg, this.converterTypeName.getText());
        context.setContextTypeFull(this.cxtClassName.getText());
        context.setAggTypeFull(this.aggClassName.getText());
        context.setResultTypeFull(this.resultClassName.getText());

        String content = ResultConverterTemplate.create(context);
        JavaFileCreator.createJavaFileInPackage(this.project,
                this.module, this.pkg, this.converterTypeName.getText(), content);

    }
}
